/*
 *  Created at 2011-12-07 20:48 GMT-03:00
 *  Author: Victor Williams Stafusa da Silva
 *  JSmartUnit
 */
package org.jsmartunit.invocations;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.jsmartunit.model.InstanceFactory;
import org.jsmartunit.model.TestRunner;

import org.junit.Test;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;

/**
 * @author Victor Williams Stafusa da Silva
 */
public class SingleInstanceAllMethodsInvocation implements Invocation {

    private final RunNotifier notifier;
    private final InstanceFactory<?> instanceFactory;
    private final String prefix;

    public SingleInstanceAllMethodsInvocation(String prefix, RunNotifier notifier, InstanceFactory<?> instanceFactory) {
        if (prefix == null) throw new IllegalArgumentException();
        if (notifier == null) throw new IllegalArgumentException();
        if (instanceFactory == null) throw new IllegalArgumentException();

        this.prefix = prefix;
        this.notifier = notifier;
        this.instanceFactory = instanceFactory;
    }

    public TestRunner createRunner() throws InitializationError {
        TestRunner runner = new TestRunner(prefix, instanceFactory.getTargetClass().getAnnotations());
        runner.addChildren(addTestMethodChildren());
        runner.setStatement(runner.getChildrenRunnerStatement());
        if (runner.getOrderedChildren().isEmpty()) throw new InitializationError("No runnable methods");
        return runner;
    }

    private List<TestRunner> addTestMethodChildren() {
        List<TestRunner> runners = new ArrayList<TestRunner>(50);

        for (Method m : instanceFactory.getTargetClass().getMethods()) {
            if (!m.isAnnotationPresent(Test.class)) continue;
            MethodInvocationArgumentBuilder builder = new MethodInvocationArgumentBuilder(prefix + "-", notifier, instanceFactory, m);
            runners.addAll(builder.runnersFor());
        }

        return runners;
    }
}
